home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Taifun / Taifun 058 (1988-05-15)(Ossowski, Stefan)(DE)(PD).zip / Taifun 058 (1988-05-15)(Ossowski, Stefan)(DE)(PD).adf / QT2 / qt2.asm < prev    next >
Assembly Source File  |  1988-04-17  |  11KB  |  419 lines

  1.     ttl    'QT2 - approximate time display (version 87/10/05)'
  2.  
  3. sys    macro            ;Call a system routine.
  4.     ifnd    _LVO\1
  5.     xref    _LVO\1
  6.     endc
  7.     jsr    _LVO\1(a6)
  8.     endm
  9.  
  10.     code
  11. *
  12. * Equates
  13. *
  14. lf    equ    $0A        ;Line feed
  15. cr    equ    $0D        ;Carriage return
  16. pr_MsgPort equ    $5C
  17. pr_CLI    equ    $AC
  18. CMD_WRITE equ    3        ;Write command
  19.  
  20. *
  21. * External references (most are taken care of by the SYS macro)
  22. *
  23.     xref    _AbsExecBase
  24.     xref    _CreatePort
  25.     xref    _DeletePort
  26.     xdef    _SysBase
  27.     xdef    _DOSBase
  28.  
  29. *
  30. * Initialization
  31. *
  32. start:    move.l    sp,savesp    ;Save the stack    pointer.
  33.     clr.l    _DOSBase    ;Clear library pointers.
  34.     clr.l    intbase
  35.     clr.l    trnbase
  36.     clr.l    voice_port
  37. * Open dos.library
  38.     move.l    _AbsExecBase,a6    ;Find library
  39.     move.l    a6,_SysBase
  40.     lea    dosname,a1    ;'dos.library'
  41.     moveq    #0,d0        ;Any version
  42.     sys    OpenLibrary    ;Open dos.library.
  43.     move.l    d0,_DOSBase    ;Save it for future reference.
  44.     beq    quitprg        ;Couldn't get pointer.
  45. * Find out whether we were called from a CLI.
  46.     suba.l    a1,a1
  47.     move.l    _SysBase,a6
  48.     sys    FindTask    ;Find our task control block.
  49.     move.l    d0,a4
  50.     move.l    pr_CLI(a4),prcli ;Save pointer to CLI.
  51.     beq.s    openwb        ;We were called from Workbench.
  52. * Get file handles for stdin and stdout.
  53.     move.l    _DOSBase,a6    ;Pointer to dos.library
  54.     sys    Input        ;Get file handle for keyboard.
  55.     move.l    d0,stdin    ;Save it here.
  56.     beq    quitprg        ;Couldn't get keyboard handle.
  57.     sys    Output        ;Get file handle for screen.
  58.     move.l    d0,stdout    ;Save it here.
  59.     beq    quitprg        ;Couldn't get screen handle.
  60.     bra.s    openint
  61. * Special Workbench startup stuff
  62. openwb    lea    pr_MsgPort(a4),a0
  63.     move.l    _SysBase,a6
  64.     sys    WaitPort    ;Wait for startup message from Workbench.
  65.     lea    pr_MsgPort(a4),a0
  66.     sys    GetMsg        ;Get the message.
  67.     move.l    d0,retmsg    ;Save it so we can return it when we're done.
  68.  
  69. * Open intuition.library
  70. openint    move.l    _SysBase,a6
  71.     lea    intname,a1
  72.     moveq    #0,d0
  73.     sys    OpenLibrary
  74.     move.l    d0,intbase
  75.     bne.s    opened        ;We got it opened.
  76.     lea    interr,a0
  77.     bsr    pstring        ;Indicate open failure.
  78.     bra    quitprg        ;Exit.
  79. opened:
  80.  
  81. *
  82. * Get the time and convert it to cute notation.
  83. *
  84. * Get the time - put hour in D6 and minute in D7.
  85.     move.l    _DOSBase,a6
  86.     move.l    #dtstamp,d1
  87.     sys    DateStamp    ;Get the time.
  88.     move.l    dtstamp+4,d7    ;Work with the time here.
  89.     divu    #60,d7        ;Convert to hours and minutes.
  90.     moveq    #0,d6
  91.     move.w    d7,d6        ;Work with hours here.
  92.     clr.w    d7
  93.     swap    d7        ;Get minutes in low-order word.
  94.     lea    timemsg,a2    ;A2 loads the final message.
  95.     lea    its,a0
  96.     bsr    copy        ;"It's "
  97. * Adjust for minutes "to" the next hour if it's after (approximately) half past.
  98.     cmpi.w    #33,d7        ;33 minutes or more past the hour?
  99.     bcs.s    adjhr        ;No.
  100.     addq.l    #1,d6        ;It's time "to" the next hour.
  101. adjhr    cmpi.w    #13,d6        ;Is it in the afternoon?
  102.     bcs.s    adj12        ;No.
  103.     subi.w    #12,d6        ;Keep it in the range 1..12
  104. adj12    tst.w    d6        ;Is hour zero?
  105.     bne.s    adj5        ;No.
  106.     moveq    #12,d6        ;Set hour to 12.
  107. * Look up nearness to a 5-minute interval.
  108. adj5    addq.l    #2,d7        ;Adjust for 5-minute rounding
  109.     cmpi.w    #60,d7
  110.     bcs.s    near
  111.     sub.w    #60,d7        ;Adjust for carry into the next hour.
  112. * Express how near we are to the 5-minute interval.
  113. near    divu    #5,d7        ;Divide adjusted minute by 5.
  114.     swap    d7        ;Get the remainder
  115.     move.w    d7,d0
  116.     asl.w    #2,d0        ;Multiply by 4 for longword displacement
  117.     lea    nearptr,a0
  118.     move.l    0(a0,d0.w),a0    ;Pointer to appropriate "near" phrase
  119.     bsr    copy        ;Copy phrase to string.
  120. * Now put in the appropriate 5-minute phrase itself.
  121.     swap    d7        ;(minute+2)/5
  122.     asl.w    #2,d7
  123.     lea    minptr,a0
  124.     move.l    0(a0,d7.w),a0    ;Pointer to appropriate minute phrase
  125.     bsr    copy
  126. * Say whether it's past the previous hour or approaching the next hour.
  127.     tst.b    d7        ;Is it around the hour?
  128.     beq.s    hrname        ;Yes - don't say anything here.
  129.     lea    past,a0        ;Assume it's past the hour
  130.     cmpi.w    #28,d7        ;Is it approaching the next hour?
  131.     bcs.s    pastto        ;No.
  132.     lea    to,a0
  133. pastto    bsr    copy
  134. * Now add the hour name.
  135. hrname    subq.l    #1,d6        ;Convert 1..12 to 0..11
  136.     asl.w    #2,d6
  137.     lea    hrptr,a0
  138.     move.l    0(a0,d6.w),a0
  139.     bsr    copy
  140. * Finish off the string and display it.
  141.     tst.w    d7        ;Is it around the hour?
  142.     bne.s    moveper        ;No.
  143.     lea    oclock,a0
  144.     bsr    copy        ;Add " o'clock".
  145. moveper    lea    period,a0
  146.     bsr    copy        ;Finish off the message.
  147.     move.l    a2,d0        ;Save ending address.
  148.     subq.l    #1,d0        ;Back over the terminating null.
  149.     lea    timemsg,a0
  150.     sub.l    a0,d0        ;Length of string
  151.     move.l    d0,timelen
  152.     tst.l    prcli        ;Were we called from a CLI?
  153.     beq.s    saytime        ;No - just say the time.
  154.     bsr    pstring        ;Display the time.
  155.  
  156. *
  157. * Now say the time (if we can!).
  158. *
  159. saytime
  160.  
  161. * Translate the string to phonemes.
  162.     move.l    _SysBase,a6
  163.     lea    trnname,a1
  164.     moveq    #0,d0
  165.     sys    OpenLibrary    ;Open translator.library.
  166.     move.l    d0,trnbase
  167.     beq    notalk        ;The open failed - forget it.
  168.     lea    timemsg,a0    ;Address of original string
  169.     move.l    timelen,d0    ;Length of original string
  170.     lea    tranmsg,a1    ;Address of translated string
  171.     moveq    #tranmax,d1    ;Maximum length
  172.     move.l    trnbase,a6
  173.     sys    Translate    ;Translate the string.
  174.  
  175. * Open a reply port for the narrator.
  176.     clr.l    -(sp)
  177.     clr.l    -(sp)
  178.     jsr    _CreatePort    ;voice_port = CreatePort (0L, 0L);
  179.     add.l    #8,sp
  180.     move.l    d0,voice_port
  181.     move.l    d0,mn_ReplyPort
  182.     beq    notalk        ;Couldn't create the port!
  183.  
  184. * Set up the write channel information.
  185.     move.l    #audio_chan,ch_masks
  186.     move.w    #audio_chan_len,nm_masks
  187.     clr.b    mouths
  188.     move.w    #CMD_WRITE,io_Command
  189.     clr.l    io_Offset
  190.     move.l    #voice_io_len,mn_Length
  191.     lea    tranmsg,a0
  192.     move.l    a0,io_Data
  193. tranlen    tst.b    (a0)+
  194.     bne.s    tranlen        ;Determine length of phoneme string.
  195.     suba.l    #1,a0
  196.     sub.l    io_Data,a0
  197.     move.l    a0,io_Length
  198.  
  199. * Open the device and say the time.
  200.     lea    narname,a0
  201.     moveq    #0,d0
  202.     lea    voice_io,a1
  203.     moveq    #0,d1
  204.     move.l    _SysBase,a6
  205.     sys    OpenDevice
  206.     tst.l    d0        ;Were we successful?
  207.     bne    notalk        ;No.
  208.  
  209.     lea    voice_io,a1
  210.     move.l    _SysBase,a6
  211.     sys    DoIO        ;Say the time.
  212.  
  213.     lea    voice_io,a1
  214.     move.l    _SysBase,a6
  215.     sys    CloseDevice    ;Close narrator.device.
  216.  
  217.     bra.s    quitprg        ;We made it!
  218.  
  219. * We were unable to talk - display a requester saying so.
  220. notalk    suba.l    a0,a0
  221.     lea    notalki,a1
  222.     suba.l    a2,a2
  223.     lea    foritxt,a3
  224.     moveq    #0,d0
  225.     moveq    #0,d1
  226.     move.l    #200,d2
  227.     moveq    #50,d3
  228.     move.l    intbase,a6
  229.     sys    AutoRequest    ;Display the requester.
  230.  
  231. *
  232. * End of program, one way or another
  233. *
  234. quitprg    move.l    savesp,sp    ;Restore stack pointer.
  235.  
  236.     move.l    voice_port,d0
  237.     beq.s    clostrn
  238.     move.l    d0,-(sp)
  239.     jsr    _DeletePort    ;Delete the narrator message port.
  240.     add.l    #4,sp
  241.  
  242. clostrn    move.l    _SysBase,a6
  243.     move.l    trnbase,d0    ;Close translator.library.
  244.     beq.s    closint        ;It wasn't opened.
  245.     move.l    d0,a1
  246.     sys    CloseLibrary
  247.  
  248. closint    move.l    intbase,d0    ;Close intuition.library.
  249.     beq.s    closdos
  250.     move.l    d0,a1
  251.     sys    CloseLibrary
  252.  
  253. closdos    move.l    _DOSBase,d0    ;Close dos.library.
  254.     beq.s    endwb
  255.     move.l    d0,a1
  256.     sys    CloseLibrary
  257.  
  258. endwb    tst.l    prcli        ;Were we called from a CLI?
  259.     bne.s    exit0        ;Yes.
  260.     move.l    _SysBase,a6
  261.     sys    Forbid        ;Don't let Workbench UnLoadSeg() us.
  262.     move.l    retmsg,a1
  263.     sys    ReplyMsg    ;Return the startup message to Workbench.
  264.  
  265. exit0    moveq    #0,d0        ;Return    with no    error.
  266.     rts            ;All done
  267.  
  268. *
  269. * Copy the null-terminated string pointed to by A0 to (A2).
  270. *  On exit, A2 points to the last byte copied (i.e. the null).
  271. *
  272. copy    move.b    (a0)+,(a2)+    ;Move one character.
  273.     bne.s    copy        ;Get the next character.
  274.     suba.l    #1,a2        ;Back over the null.
  275.     rts
  276.  
  277. *
  278. * Display the null-terminated string pointed to by A0.
  279. *
  280. pstring    movem.l    d2-d3/a6,-(sp)
  281.     move.l    a0,d2        ;AmigaDOS wants the address here.
  282. pstrl    tst.b    (a0)+        ;Scan for end of string.
  283.     bne.s    pstrl
  284.     move.l    a0,d3        ;AmigaDOS wants the length here.
  285.     sub.l    d2,d3        ;Length plus one
  286.     subq.l    #1,d3        ;Reduce to proper length.
  287.     move.l    stdout,d1
  288.     move.l    _DOSBase,a6
  289.     sys    Write        ;Write the string.
  290.     movem.l    (sp)+,d2-d3/a6
  291.     rts
  292.     page
  293. *************************************************************************
  294. *                                    *
  295. *    Constants                            *
  296. *                                    *
  297. *************************************************************************
  298.  
  299.     section    Constants,data
  300.  
  301. dosname    dc.b    'dos.library',0
  302. intname    dc.b    'intuition.library',0
  303. trnname    dc.b    'translator.library',0
  304. interr    dc.b    'Unable to open intuition.library',cr,lf,0
  305. narname    dc.b    'narrator.device',0
  306. notalkm    dc.b    'I can''t talk!',0
  307. fortext    dc.b    'Forget it',0
  308. its    dc.b    'It''s ',0
  309. nearptr    dc.l    almost,nearly,null,justaft,justpas
  310. almost    dc.b    'almost ',0
  311. nearly    dc.b    'nearly ',0
  312. null    dc.l    0
  313. justaft    dc.b    'just after ',0
  314. justpas    dc.b    'just past ',0
  315. minptr    dc.l    null,five,ten,quarter,twenty,twenfiv,half
  316.     dc.l    twenfiv,twenty,quarter,ten,five
  317. quarter    dc.b    'a quarter',0
  318. half    dc.b    'half',0
  319. hrptr    dc.l    one,two,three,four,five,six,seven,eight,nine,ten,eleven,twelve
  320. one    dc.b    'one',0
  321. two    dc.b    'two',0
  322. three    dc.b    'three',0
  323. four    dc.b    'four',0
  324. five    dc.b    'five',0
  325. six    dc.b    'six',0
  326. seven    dc.b    'seven',0
  327. eight    dc.b    'eight',0
  328. nine    dc.b    'nine',0
  329. ten    dc.b    'ten',0
  330. eleven    dc.b    'eleven',0
  331. twelve    dc.b    'twelve',0
  332. twenty    dc.b    'twenty',0
  333. twenfiv    dc.b    'twenty-five',0
  334. to    dc.b    ' to ',0
  335. past    dc.b    ' past ',0
  336. oclock    dc.b    ' o''clock',0
  337. period    dc.b    '.',cr,lf,0
  338.  
  339. audio_chan dc.b    3,5,10,12    ;Which audio channels to use
  340. audio_chan_len    equ    *-audio_chan
  341.  
  342. * IntuiText structures for "can't-talk" requester
  343.     cnop    0,4
  344. notalki                ;BodyText
  345.     dc.b    0,1,0,0
  346.     dc.w    10,5
  347.     dc.l    0,notalkm,0
  348. foritxt                ;NegativeText
  349.     dc.b    0,1,0,0
  350.     dc.w    4,3
  351.     dc.l    0,fortext,0
  352.     page
  353. *************************************************************************
  354. *                                    *
  355. *    Storage areas                            *
  356. *                                    *
  357. *************************************************************************
  358.  
  359.     section Storage,bss
  360.  
  361. savesp    ds.l    1        ;Stack pointer save area
  362. retmsg    ds.l    1        ;Pointer to Workbench startup message
  363. _SysBase ds.l    1        ;Copy of _AbsExecBase
  364. _DOSBase ds.l    1        ;Pointer to dos.library
  365. intbase    ds.l    1        ;Pointer to intuition.library
  366. trnbase    ds.l    1        ;Pointer to translator.library
  367. prcli    ds.l    1        ;Pointer to CLI or zero
  368. stdin    ds.l    1        ;stdin file handle
  369. stdout    ds.l    1        ;stdout file handle
  370. dtstamp    ds.l    3        ;Date stamp (days, minutes, ticks)
  371. timemsg    ds.b    41        ;Time message is built here.
  372. timelen    ds.l    1        ;Actual length of time message
  373. tranmsg    ds.b    80        ;"timemsg" translated to phonemes
  374. tranmax    equ    *-tranmsg
  375. voice_port ds.l    1        ;Pointer to message port for narrator.device
  376.  
  377. *
  378. * Narrator write request
  379. *
  380. voice_io    ;struct narrator_rb
  381. message        ;struct IOStdReq
  382. io_Message    ;struct Message
  383. mn_Node        ;struct Node
  384. ln_Succ    ds.l    1    ;Pointer to successor Node
  385. ln_Pred    ds.l    1    ;Pointer to predecessor Node
  386. ln_Type    ds.b    1
  387. ln_Pri    ds.b    1 
  388. ln_Name    ds.l    1    ;Pointer 
  389.         ; End of struct Node
  390. mn_ReplyPort    ds.l 1    ;Pointer to MsgPort (message reply port)
  391. mn_Length ds.w    1    ;Message length in bytes
  392.         ; End of struct Message
  393. io_Device ds.l    1    ;Pointer to device node
  394. io_Unit    ds.l    1    ;Pointer to Unit (driver private)
  395. io_Command ds.w    1    ;Device command
  396. io_Flags ds.b    1
  397. io_Error ds.b    1    ;Error or warning number
  398.         ; End of struct IOReq - IOStdReq continues...
  399. io_Actual ds.l    1    ;Actual number of bytes transferred
  400. io_Length ds.l    1    ;Requested number of bytes transferred
  401. io_Data    ds.l    1    ;Points to data area.
  402. io_Offset ds.l    1    ;Offset for block-structured devices
  403.         ; End of struct IOStdReq
  404. rate    ds.w    1    ;Speaking rate (words per minute)
  405. pitch    ds.w    1    ;Baseline pitch in Hertz
  406. mode    ds.w    1    ;Pitch mode
  407. sex    ds.w    1    ;Sex of voice
  408. ch_masks ds.l    1    ;Pointer to audio allocation maps
  409. nm_masks ds.w    1    ;Number of audio allocation maps
  410. volume    ds.w    1    ;Volume: 0 (off) thru 64 (maximum)
  411. sampfreq ds.w    1    ;Audio sampling frequency
  412. mouths    ds.b    1    ;If non-zero, generate mouths.
  413. chanmask ds.b    1    ;Which channel mask used (internal)
  414. numchan    ds.b    1    ;Number of channel masks used (internal)
  415.     ds.b    1    ;For alignment
  416. voice_io_len equ *-voice_io    ; End of struct narrator_rb
  417.  
  418.     end
  419.